//
//  NSBase.swift
//  ocapp
//
//  Created by zhuxietong on 2018/8/23.
//

public extension String {
    
    func char(at:Int) -> String {
        if at < self.count
        {
            NSMutableArray().list { (One:String, i) in
                
            }
            let s = self.index(self.startIndex, offsetBy: at)
            let e = self.index(self.startIndex, offsetBy: at+1)
            
            let subvalues = self[s..<e] // One-sided Slicing
            return String(subvalues)
        }
        return ""
    }
    
    
    //    subscript (index: Int) -> Character {
    //        return self[self.characters.index(self.startIndex, offsetBy: index)]
    //    }
    //
    //    subscript (range: Range<Int>) -> String {
    //        return String(self[self.characters.index(self.startIndex, offsetBy: range.lowerBound)..<self.characters.index(self.startIndex, offsetBy: range.upperBound)])
    //    }
    
    public func sub(from:Int,end:Int) -> String {
        let s = self.index(self.startIndex, offsetBy: from)
        let e = self.index(self.startIndex, offsetBy: end)
        
        let subvalues = self[s..<e] // One-sided Slicing
        return String(subvalues)
        
        //        return String(self[self.characters.index(self.startIndex, offsetBy: from)..<self.characters.index(self.startIndex, offsetBy: end)])
    }
}


internal class JoArrayGenerator<T>:IteratorProtocol
{
    typealias Element = T
    var list:NSArray
    var validate_list = NSMutableArray()
    
    var count:Int = 0
    init(list:NSArray)
    {
        self.list = list
        
        validate_list.removeAllObjects()
        for obj in self.list
        {
            if let _ = obj as? T
            {
                validate_list.add(obj)
            }
        }
        self.count = 0
    }
    
    
    func next() -> Element? {
        if self.count < self.validate_list.count
        {
            let one = self.validate_list[count] as? Element
            count += 1
            
            return one
        }
        
        self.count  = 0
        return nil
        
    }
    
}

class JoArray<T> :Sequence{
    
    typealias Iterator = JoArrayGenerator<T>
    var list:NSArray
    
    func makeIterator() -> Iterator {
        return JoArrayGenerator(list: list)
    }
    
    init(list:NSArray)
    {
        self.list = list
    }
    
}

public extension NSArray
{
    public func reverse_list<T>(_ block:(T,Int)->Void) {
        let list = self.reversed()
        var index:Int = 0
        for one in JoArray<T>(list: list as NSArray)
        {
            block(one,index)
            index += 1
        }
    }
    
    public func list<T>(_ block:(T,Int)->Void)
    {
        
        var index:Int = 0
        for one in JoArray<T>(list: self)
        {
            block(one,index)
            index += 1
        }
        
    }
    
    
    public func listObj<T>(_ block:(T)->Void)
    {
        
        for one in JoArray<T>(list: self)
        {
            block(one)
        }
        
    }
    
    
}

public extension Array{
    
    public func new<T,Obj>(_ creator:(Int,Obj)throws->T) ->[T]{
        
        var new_list = [T]()
        for (index,one) in self.enumerated()
        {
            if let o = one as? Obj
            {
                do {
                    let one = try creator(index,o)
                    new_list.append(one)
                } catch {
                    print(error)
                }
                
                
            }
        }
        return new_list
    }
}


public extension Array
{
    var mutable_array:NSMutableArray
    {
        return (self as NSArray).mutable_array
    }
    
}


public extension Dictionary
{
    var mutable_dictionary:NSMutableDictionary
    {
        return (self as NSDictionary).mutable_dictionary
    }
}


public extension NSArray
{
    var mutable_array:NSMutableArray{
        let mutable_a = NSMutableArray()
        for v in self
        {
            switch v {
            case let dic as NSDictionary:
                mutable_a.add(dic.mutable_dictionary);break
            case let arr as NSArray:
                mutable_a.add(arr.mutable_array);break
            case let str as String:
                mutable_a.add(str);break
            case let int as Int64:
                mutable_a.add(int);break
            case let int as Int32:
                mutable_a.add(int);break
            case let int as Int:
                mutable_a.add(int);break
            case let flt as Float:
                mutable_a.add(flt);break
            case let dbl as Double:
                mutable_a.add(dbl);break
            case let cgf as CGFloat:
                mutable_a.add(cgf);break
            default:
                mutable_a.add(v)
            }
        }
        return mutable_a
    }
}

public extension NSDictionary
{
    var mutable_dictionary:NSMutableDictionary
    {
        let mutable_d = NSMutableDictionary()
        for (k,v) in self
        {
            switch v {
            case let dic as NSDictionary:
                mutable_d[k] = dic.mutable_dictionary;break
            case let arr as NSArray:
                mutable_d[k] = arr.mutable_array;break
            case let str as String:
                mutable_d[k] = str;break
            case let int as Int64:
                mutable_d[k] = int;break
            case let int as Int32:
                mutable_d[k] = int;break
            case let int as Int:
                mutable_d[k] = int;break
            case let flt as Float:
                mutable_d[k] = flt;break
            case let dbl as Double:
                mutable_d[k] = dbl;break
            case let cgf as CGFloat:
                mutable_d[k] = cgf;break
            default:
                mutable_d[k] = v;break
            }
        }
        return mutable_d
    }
}
